<?php

namespace app\service\payment\gateway;

use app\constant\CommonConstant;
use app\exception\BusinessException;
use app\libs\AsiabillSDK\action\CheckoutAsiabill;
use app\libs\AsiabillSDK\builder\CheckoutBuilder;
use app\libs\AsiabillSDK\builder\RepurchaseBuilder;
use app\model\Notify;
use app\model\Orders;
use think\helper\Arr;
use think\helper\Str;
use think\Request;

class AsiabillService implements PaymentInterface
{
    public function placeOrder(Orders $order, Request $request)
    {
        //正常支付
        $customerPaymentMethodId = $request->param('customerPaymentMethodId');
        if (empty($customerPaymentMethodId)) throw new BusinessException('asibill payment require customerPaymentMethodId');
        $order->payment_token = ['customerPaymentMethodId' => $customerPaymentMethodId];
        $order->save();
        return $this->callAsiabillAPI($order, $request);
    }

    public function confirmPayment()
    {
        // TODO: Implement confirmPayment() method.
    }

    public function repurchase(Orders $order, Request $request)
    {
        return $this->callAsiabillAPI($order, $request);
    }


    public function getAsiabillReturnUrl(Orders $order, Request $request)
    {
        list($returnUrl, $cancelUrl) = Orders::getContextApplicationUrl($order,$request);
        return $cancelUrl;
    }

    //提取调用
    private function callAsiabillAPI(Orders $order, Request $request)
    {
        $log = null;
        try {
            $checkout = new CheckoutAsiabill($order->payment);
            $returnUrl = $this->getAsiabillReturnUrl($order, $request);
            $customerPaymentMethodId = Arr::get($order->payment_token, 'customerPaymentMethodId');
            if ($order->is_repurchase) {
                $builder = new RepurchaseBuilder($order);
                $body = $builder
                    ->setCustomerPaymentMethodId($customerPaymentMethodId)
                    ->setReturnUrl($returnUrl)
                    ->toArray();
            } else {
                $builder = new CheckoutBuilder($order);
                $body = $builder
                    ->setCustomerPaymentMethodId($customerPaymentMethodId)
                    ->setReturnUrl($returnUrl)
                    ->toArray();
            }
            $result = $checkout->confirm_charge($body);
            $type = $order->is_repurchase ? Notify::TYPE_PLACE_ORDER : Notify::TYPE_CAPTURE_PURCHASE;
            $log = Notify::saveParams($order->id, ['params' => $body, 'result' => $result], $type, $order->pay_method);
            //保存加购结果
            $response = $this->savePayResult($result, $order);
            if (array_key_exists('paypal_approve_url', $response)) $response['paypal_approve_url'] = $returnUrl;
            return $response;
        } catch (\Exception $e) {
            if ($log) {
                $logParams = $log->params;
                $logParams['error'] = $e->getMessage();
                $log->save();
            }
            throw $e;
        }
    }

    private function savePayResult(array $pay_result, Orders $order): array
    {
        if (empty($pay_result)) throw new BusinessException(CommonConstant::PAYMENT_EXCEPTION);
        $data = Arr::get($pay_result, 'data', []);
        $orderStatus = Arr::get($data, 'orderStatus', '');
        $order->pay_status = $orderStatus;
        $order->trade_no = Arr::get($data, 'tradeNo', '');
        $order->order_no = Arr::get($data, 'orderNo', $order->name);
        $code = Arr::get($pay_result, 'code', '');
        $redirectUrl = Arr::get($pay_result, 'data.redirectUrl', '');
        $order->save();
        if ($redirectUrl) {
            return compact('redirectUrl');
        } else {
            if ($code != '00000') throw new BusinessException(Arr::get($pay_result, 'message', CommonConstant::PAYMENT_EXCEPTION));
            if ($orderStatus == 'fail') throw new BusinessException(Arr::get($data, 'orderInfo', CommonConstant::PAYMENT_EXCEPTION));
            if ($orderStatus == 'pending') throw new BusinessException(CommonConstant::PAYMENT_EXCEPTION);
            $transaction_id = Arr::get($data, 'tradeNo', "");
            $paypal_approve_url = '';
            return compact('transaction_id', 'paypal_approve_url', 'pay_result');
        }
    }


}